home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagd_f.zip / DOS.SWG / 0047_Loading Overlays in XMS.pas < prev    next >
Pascal/Delphi Source File  |  1994-02-03  |  13KB  |  459 lines

  1.  
  2. {
  3. With this unit, it doesn't matter if the overlay is separate,
  4. or tacked onto the end of the .EXE file -- the program will
  5. run either way.
  6.  
  7. As written, this unit also uses OVERXMS, a PD unit written
  8. Wilbert Van Leijen.  Floating around the BBS's as OVERXMS.ZIP
  9. You may delete the references to XMS.
  10. The XMS stuff is in there because the program I copied this
  11. code from will run on a 486 and just about all of the college
  12. machines have XMS memory -- few if any have EMS. }
  13.  
  14. {$A-,B+,D-,F+,I-,L-,N-,O-,Q+,R-,S-,V-}
  15.  
  16. UNIT RVOVRLAY;
  17.  
  18. { This unit starts the overlay manager }
  19.  
  20. INTERFACE
  21. Const
  22.   ovrNoXMSDriver = -7;   { No XMS driver installed }
  23.   ovrNoXMSMemory = -8;   { Insufficient XMS memory available }
  24.  
  25.  
  26. IMPLEMENTATION
  27.  
  28. USES DOS, OVERLAY;
  29.  
  30. { OVERXMS - Loads overlays in XMS.
  31.   Assembly-language portion written by Wilbert van Leijen }
  32. Procedure OvrInitXMS; External;
  33. {$L OVERXMS.OBJ }
  34.  
  35. Function Exist(Filename:string):boolean;
  36. {returns true if file exists}
  37.  
  38. var Inf: SearchRec;
  39.  
  40. begin
  41.   FindFirst(Filename,AnyFile,Inf);
  42.   Exist := (DOSError = 0);
  43. end;  {Func Exist}
  44.  
  45.  
  46. Procedure S_Write (Msg : string);
  47.  
  48. BEGIN  {Dirty trick to generate less code}
  49.   Write (msg);
  50. END;
  51.  
  52.  
  53. Procedure WriteOvrErrMsg;
  54.  
  55. VAR
  56.   garbage:char;
  57.  
  58. BEGIN
  59.   WRITE ('Overlay error: ',OvrResult,'  ');
  60.   IF (OvrResult = ovrOk) THEN S_WRITE ('Ok - No error');
  61.   IF (OvrResult = ovrError) THEN S_WRITE ('Missing Overlay error');
  62.   IF (OvrResult = ovrNotFound) THEN S_WRITE ('Overlay file not found');
  63.   IF (OvrResult = ovrNoMemory) THEN S_WRITE ('No Memory for overlays');
  64.   IF (OvrResult = ovrIOError) THEN S_WRITE ('Overlay IO Error');
  65.   IF (OvrResult = ovrNoEMSDriver) THEN S_WRITE ('No EMS Driver');
  66.   IF (OvrResult = ovrNoEMSMemory) THEN S_WRITE ('No EMS Memory');
  67.   IF (OvrResult = ovrNoXMSDriver) THEN S_WRITE ('No XMS Driver');
  68.   IF (OvrResult = ovrNoXMSMemory) THEN S_WRITE ('No XMS Memory');
  69.   S_WRITE (^M^J);
  70.   read (garbage);
  71.   If OvrResult <> OvrOK THEN HALT (98);
  72. END;  { Procedure WriteOvrErrMsg }
  73.  
  74.  
  75. BEGIN      { main }
  76.  
  77.   IF (lo(DosVersion) < 3) THEN
  78.     BEGIN
  79.       WriteLn ('You are using DOS version ',Lo(DosVersion),
  80.                '.',Hi(DosVersion));
  81.       Writeln ('Mulesoft Revenge requires DOS v3.0 or greater.');
  82.       HALT (99);
  83.     END;
  84.  
  85.   { Start overlay manager and assume that overlay is in
  86.     the .EXE file.  If not found in .EXE file, assume the
  87.     overlay file is separate from the .EXE file. }
  88.  
  89.   OVRINIT (paramstr(0));
  90.  
  91.   If (OvrResult = ovrError) THEN  { Overlay not at end of .EXE file }
  92.     OVRINIT (copy(paramstr(0), 1, Length(paramstr(0))-3) + 'OVR');
  93.   IF (OvrResult <> OvrOk) THEN
  94.       WriteOvrErrMsg
  95.   ELSE     { Try to load the overlay into XMS memory }
  96.     BEGIN
  97.       OvrInitXms;
  98.       IF (OvrResult <> OvrOk) THEN
  99.         OvrInitEms;
  100.     END;
  101. END.
  102.  
  103. {------------------------- snip, snip ----------------------------}
  104.  
  105.    Here is the .OBJ file that goes with this file ...
  106.    you will need XX3402 o decode this output:
  107.  
  108.    Cut this out to a file named OVERXMS.XX.
  109.    Execute XX3402 d OVERXMS.XX
  110.  
  111.    You will then get the file OVERXMS.OBJ to compile this unit
  112.  
  113. *XX3402-000913-020294--72--85-48736-----OVERXMS.OBJ--1-OF--1
  114. U+o+0qxqNL7sPLAiEJBBFMUU++++53FpQa7j623nQqJhMalZQW+UJaJmQqZjPW+n9X8NW-A+
  115. ECafC26Q0qxqNL7sPLAiEJBBnMU1+21dH7M0++-cW+A+E84IZUM+-2F-J234a+Q+G-c++U2-
  116. ytM4++F1HoF3FNU5+0Wi+EA-+MKAJ++7I373FYZMIoJ5++V3K2ZII37DEk+7HpNGIYJHJIlI
  117. ++hDJZ71HoF3H2ZHJ++AHpNGF2xHG23CF2l3++dDJZ76FI3EHp75++dDJZ7GFI32EZJ4+0OE
  118. 2E+++UdDJZ77HYZIK2pHCE2+xcU2+20W+N4UgU20++093VU+h+fz5U++l+M2+8A++6k4+U19
  119. Aw+nocgS+++15U++UwAEXgAa+kM6+6DG+0O95Us+0xhptfg+-DTnYY8o0TwS+++9k5E2WFMM
  120. +ABJWymCFUMacEU+ckU+Aw0X0U0V4+0X1++acFM+cks+7e2M+8AE+1D+cl6+clE+7e2E+8AK
  121. +9E9jUU+zls+++j+R+F6ukGEiDnzLQc0+0O93UU+xw6-+5E4EWPz-UU+WFM6+1D+ckc+ckk+
  122. cks+cE++cl++cFU+cl6+WHsI+6YS3U0o0vs6+DwS+++1ycDH++j+R+9skzb1JMjgcE++AwY1
  123. -U++-F++Xg-EEGOV1U+9k5LhAxgnzkRFcE++7eAE+0O75VU+7cYy3U-HJkM4zls+++RTKmP5
  124. -V++++1rq566u4jzQUBNsgy9tJr1Aw+v-U++REF6uqOEi+-1nGwwU5E4iDbzupSEi--1nGy7
  125. 5U++X+M0+CWmzbI4iDXzunyEu5PzQl093VU+h+fz5U++iDnzumeEWls++9EynG55-U++HU0A
  126. 1U6+l+M++8A2+6k4-U15-U++++0A1U6+Aw0X++19RdnW+AE0J+5203E-l+lI+QED-U20l-A4
  127. +E925+M--AEU-U2-l2BI+QF9J+52KJE-l3tI+QFVJ+52N3E-l4hI+QFmJ+52RpE-l5dI+QG-
  128. J+52VZE-l6dI+QGiJ+52gpE-l9NI+QGtJ+52j+M--gGzJ+52kZE-lAJI+QH7J+52nJE-lB7I
  129. +QHKJ+52uEM--AHj-U2-lEQ4+EP35EM--wIx-U23lJhI+QJTJ+53QpE-lLZI+QK1-U23lMg4
  130. +ET3XJE0lN24+ET3ZEM-+gKMJ+53b3E-lO+4+E93cZE0lOM4+E93ekM-+z88+U++R+++
  131. ***** END OF BLOCK 1 *****
  132.  
  133. {---------------------         OVERXMS.ASM   --------------------- }
  134. {                          NEED MASM,TASM to compile               }
  135.  
  136. TITLE Turbo Pascal XMS support for loading overlays - By Wilbert van Leijen
  137. PAGE 65, 132
  138. LOCALS @@
  139.  
  140. Data       SEGMENT Word Public
  141.            ASSUME  DS:Data
  142.  
  143. ;  XMS block move record
  144.  
  145. XmsMoveType STRUC
  146.            BlkSize     DD    ?
  147.            SrcHandle   DW    ?
  148.            SrcOffset   DD    ?
  149.            DestHandle  DW    ?
  150.            DestOffset  DD    ?
  151. XmsMoveType ENDS
  152.  
  153. ;  TP overlay manager record
  154.  
  155. OvrHeader  STRUC
  156.            ReturnAddr  DD    ?         ; Virtual return address
  157.            FileOfs     DD    ?         ; Offset into overlay file
  158.            CodeSize    DW    ?         ; Size of overlay
  159.            FixupSize   DW    ?         ; Size of fixup table
  160.            EntryPts    DW    ?         ; Number of procedures
  161.            CodeListNext DW   ?         ; Segment of next overlay
  162.            LoadSeg     DW    ?         ; Start segment in memory
  163.            Reprieved   DW    ?         ; Loaded in memory flag
  164.            LoadListNext DW   ?         ; Segment of next in load list
  165.            XmsOffset   DD    ?         ; Offset into allocated XMS block
  166.            UserData    DW    3 DUP(?)
  167. OvrHeader  ENDS
  168.  
  169. XmsDriver  DD      ?                   ; Entry point of XMS driver
  170. ExitSave   DD      ?                   ; Pointer to previous exit proc
  171. XmsMove    XmsMoveType <>
  172. OvrXmsHandle DW    ?                   ; Returned by XMS driver
  173.  
  174.            Extrn   PrefixSeg : Word
  175.            Extrn   ExitProc : DWord
  176.            Extrn   OvrResult : Word
  177.            Extrn   OvrCodeList : Word
  178.            Extrn   OvrDosHandle : Word
  179.            Extrn   OvrHeapOrg : Word
  180.            Extrn   OvrReadBuf : DWord
  181. Data       ENDS
  182.  
  183. Code       SEGMENT Byte Public
  184.            ASSUME  CS:Code
  185.            Public  OvrInitXMS
  186.  
  187. ovrIOError     EQU     -4
  188. ovrNoXMSDriver EQU     -7
  189. ovrNoXMSMemory EQU     -8
  190.  
  191. OvrXmsExit PROC
  192.  
  193. ; Release handle and XMS memory
  194.  
  195.         MOV    DX, [OvrXmsHandle]
  196.         MOV    AH, 10
  197.         CALL   [XmsDriver]
  198.  
  199. ; Restore pointer to previous exit procedure
  200.  
  201.         LES    AX, [ExitSave]
  202.         MOV    Word Ptr [ExitProc], AX
  203.         MOV    Word Ptr [ExitProc+2], ES
  204.         RETF
  205. OvrXmsExit ENDP
  206.  
  207. AllocateXms PROC
  208.  
  209. ;  Determine the size of the XMS block to allocate:
  210. ;  Walk the CodeListNext chain
  211. ;  Store the total codesize in DX:AX
  212.  
  213.         XOR    AX, AX
  214.         XOR    DX, DX
  215.         MOV    BX, [OvrCodeList]
  216. @@1:    ADD    BX, [PrefixSeg]
  217.         ADD    BX, 10h
  218.         MOV    ES, BX
  219.         ADD    AX, ES:[OvrHeader.CodeSize]
  220.         ADC    DX, 0
  221.         MOV    BX, ES:[OvrHeader.CodeListNext]
  222.         OR     BX, BX
  223.         JNZ    @@1
  224.  
  225. ;  Obtain number of kilobytes to allocate
  226.  
  227.         MOV    BX, 1024
  228.         DIV    BX
  229.         XCHG   DX, AX
  230.         INC    DX
  231.  
  232. ;  Allocate the block
  233.  
  234.         MOV    AH, 9
  235.         CALL   [XmsDriver]
  236.         OR     AX, AX
  237.         JZ     @@2
  238.         MOV    [OvrXmsHandle], DX
  239. @@2:    RETN
  240. AllocateXms ENDP
  241.  
  242. ;  Function XmsReadFunc(OvrSeg : Word) : Integer; Far;
  243.  
  244. XmsReadFunc PROC
  245.  
  246. ;  Swap the code from XMS to the heap
  247.  
  248.         PUSH   BP
  249.         MOV    BP, SP
  250.         MOV    ES, [BP+6]
  251.         MOV    AX, ES:[OvrHeader.CodeSize]
  252.         MOV    Word Ptr [XmsMove.BlkSize], AX
  253.         XOR    AX, AX
  254.         MOV    Word Ptr [XmsMove.BlkSize+2], AX
  255.         MOV    AX, [OvrXmsHandle]
  256.         MOV    [XmsMove.SrcHandle], AX
  257.         MOV    AX, Word Ptr ES:[OvrHeader.XmsOffset]
  258.         MOV    Word Ptr [XmsMove.SrcOffset], AX
  259.         MOV    AX, Word Ptr ES:[OvrHeader.XmsOffset+2]
  260.         MOV    Word Ptr [XmsMove.SrcOffset+2], AX
  261.         XOR    AX, AX
  262.         MOV    [XmsMove.DestHandle], AX
  263.         MOV    Word Ptr [XmsMove.DestOffset], AX
  264.         MOV    AX, ES:[OvrHeader.LoadSeg]
  265.         MOV    Word Ptr [XmsMove.DestOffset+2], AX
  266.         MOV    AH, 11
  267.         LEA    SI, XmsMove
  268.         CALL   [XmsDriver]
  269.         OR     AX, AX
  270.         JZ     @@1
  271.         DEC    AX
  272.         JMP    @@2
  273.  
  274. @@1:    MOV    AX, ovrIOError
  275. @@2:    POP    BP
  276.         RETF   2
  277. XmsReadFunc ENDP
  278.  
  279. ;  Copy an overlaid unit from the heap to XMS
  280. ;  If successful, carry flag is cleared
  281. ;  In/Out:
  282. ;    BX:DI = offset into XMS memory block
  283.  
  284. CopyUnitToXms PROC
  285.  
  286. ;  XMS requires that an even number of bytes is moved
  287.  
  288.         MOV    DX, ES:[OvrHeader.CodeSize]
  289.         TEST   DX, 1
  290.         JZ     @@1
  291.         INC    DX
  292.         INC    ES:[OvrHeader.CodeSize]
  293.  
  294. ;  Get the fields of the XMS block move structure
  295.  
  296. @@1:    MOV    Word Ptr [XmsMove.BlkSize], DX
  297.         XOR    AX, AX
  298.         MOV    Word Ptr [XmsMove.BlkSize+2], AX
  299.         MOV    [XmsMove.SrcHandle], AX
  300.         MOV    Word Ptr [XmsMove.SrcOffset], AX
  301.         MOV    AX, [OvrHeapOrg]
  302.         MOV    Word Ptr [XmsMove.SrcOffset+2], AX
  303.         MOV    AX, [OvrXmsHandle]
  304.         MOV    [XmsMove.DestHandle], AX
  305.         MOV    Word Ptr [XmsMove.DestOffset], DI
  306.         MOV    Word Ptr [XmsMove.DestOffset+2], BX
  307.         MOV    AH, 11
  308.         LEA    SI, XmsMove
  309.         CALL   [XmsDriver]
  310.  
  311. ;  Bump code size
  312.  
  313.         ADD    DI, DX
  314.         ADC    BX, 0
  315.  
  316. ;  Check return code from XMS driver
  317.  
  318.         OR     AX, AX
  319.         JZ     @@2
  320.         CLC
  321.         RETN
  322.  
  323. @@2:    STC
  324.         RETN
  325. CopyUnitToXms ENDP
  326.  
  327. OvrXmsLoad PROC
  328.         PUSH   BP
  329.         MOV    BP, SP
  330.  
  331. ;  Walk the CodeList chain
  332. ;  First segment is PrefixSeg+10h+OvrCodeList
  333. ;  Push each element of overlaid unit list on the stack
  334. ;  Keep the size of the linked list in CX
  335.  
  336.         MOV    AX, [OvrCodeList]
  337.         XOR    CX, CX
  338. @@1:    ADD    AX, [PrefixSeg]
  339.         ADD    AX, 10h
  340.         MOV    ES, AX
  341.         PUSH   AX
  342.         INC    CX
  343.         MOV    AX, ES:[OvrHeader.CodeListNext]
  344.         OR     AX, AX
  345.         JNZ    @@1
  346.  
  347. ;  Loop:
  348. ;    Pop each element of the overlaid unit list from the stack
  349.  
  350.         XOR    BX, BX
  351.         XOR    DI, DI
  352. @@2:    POP    ES
  353.         PUSH   CX
  354.         MOV    AX, [OvrHeapOrg]
  355.         MOV    ES:[OvrHeader.LoadSeg], AX
  356.         MOV    Word Ptr ES:[OvrHeader.XmsOffset+2], BX
  357.         MOV    Word Ptr ES:[OvrHeader.XmsOffset], DI
  358.  
  359. ;  Load overlay from disk
  360.  
  361.         PUSH   BX
  362.         PUSH   DI
  363.         PUSH   ES
  364.         PUSH   ES
  365.         CALL   [OvrReadBuf]
  366.         POP    ES
  367.         POP    DI
  368.         POP    BX
  369.  
  370. ;  Flag unit as 'unloaded'; check return code
  371.  
  372.         MOV    ES:[OvrHeader.LoadSeg], 0
  373.         NEG    AX
  374.         JC     @@3
  375.  
  376.         CALL   CopyUnitToXms
  377.         JC     @@3
  378.  
  379.         POP    CX
  380.         LOOP   @@2
  381.  
  382. @@3:    MOV    SP, BP
  383.         POP    BP
  384.         RETN
  385. OvrXMSLoad ENDP
  386.  
  387. OvrInitXMS PROC
  388.  
  389. ;  Make sure the file's been opened
  390.  
  391.         XOR    AX, AX
  392.         CMP    AX, [OvrDOSHandle]
  393.         JNE    @@1
  394.         DEC    AX                      ; ovrError
  395.         JMP    @@5
  396.  
  397. ;  Check presence of XMS driver
  398.  
  399. @@1:    MOV    AX, 4300h
  400.         INT    2Fh
  401.         CMP    AL, 80h
  402.         JE     @@2
  403.         MOV    AX, ovrNoXmsDriver
  404.         JMP    @@5
  405.  
  406. ;  Get XMS driver's entry point
  407.  
  408. @@2:    MOV    AX, 4310h
  409.         INT    2Fh
  410.         MOV    Word Ptr [XmsDriver], BX
  411.         MOV    Word Ptr [XmsDriver+2], ES
  412.         CALL   AllocateXms
  413.         JNZ    @@3
  414.         MOV    AX, ovrNoXMSMemory
  415.         JMP    @@5
  416.  
  417. ;  Load the overlay into XMS
  418.  
  419. @@3:    CALL   OvrXmsLoad
  420.         JNC    @@4
  421.  
  422. ;  An error occurred.  Release handle and XMS memory
  423.  
  424.         MOV    DX, [OvrXmsHandle]
  425.         MOV    AH, 10
  426.         CALL   [XmsDriver]
  427.         MOV    AX, ovrIOError
  428.         JMP    @@5
  429.  
  430. ;  Close file
  431.  
  432. @@4:    MOV    BX, [OvrDOSHandle]
  433.         MOV    AH, 3Eh
  434.         INT    21h
  435.  
  436. ;  OvrReadBuf := XmsReadFunc
  437.  
  438.         MOV    Word Ptr [OvrReadBuf], Offset XmsReadFunc
  439.         MOV    Word Ptr [OvrReadBuf+2], CS
  440.  
  441. ;  ExitSave := ExitProc
  442. ;  ExitProc := OvrXmsExit
  443.  
  444.         LES    AX, [ExitProc]
  445.         MOV    Word Ptr [ExitSave], AX
  446.         MOV    Word Ptr [ExitSave+2], ES
  447.         MOV    Word Ptr [ExitProc], Offset OvrXmsExit
  448.         MOV    Word Ptr [ExitProc+2], CS
  449.  
  450. ;  Return result of initialisation
  451.  
  452.         XOR    AX, AX
  453. @@5:    MOV    [OvrResult], AX
  454.         RETF
  455. OvrInitXMS ENDP
  456.  
  457. Code       ENDS
  458.            END
  459.